package vip.xiaonuo.biz.modular.spot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.spot.entity.Spot;
import vip.xiaonuo.biz.modular.spot.mapper.SpotMapper;
import vip.xiaonuo.biz.modular.spot.param.SpotAddParam;
import vip.xiaonuo.biz.modular.spot.param.SpotEditParam;
import vip.xiaonuo.biz.modular.spot.param.SpotIdParam;
import vip.xiaonuo.biz.modular.spot.param.SpotPageParam;
import vip.xiaonuo.biz.modular.spot.result.Namelist;
import vip.xiaonuo.biz.modular.spot.service.SpotService;
import vip.xiaonuo.biz.modular.ticket.entity.Ticket;
import vip.xiaonuo.biz.modular.ticket.service.TicketService;
import vip.xiaonuo.biz.modular.user.entity.BizFzUser;
import vip.xiaonuo.biz.modular.user.mapper.BizFzUserMapper;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;

import java.math.BigDecimal;
import java.util.List;

/**
 * 景点表Service接口实现类
 *
 * @author gtc
 *
 **/
@Service
public class SpotServiceImpl extends ServiceImpl<SpotMapper, Spot> implements SpotService {

    @Autowired
    private SpotMapper spotMapper;
    @Autowired
    private TicketService ticketService;
    @Autowired
    private BizFzUserMapper bizFzUserMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    public static final String GEO_KEY = "spot:locations";



//    @PostConstruct
//    public void syncSpotsWithRedis() {
//        List<Spot> spots = this.list();
//        spots.forEach(spot -> {
//            Long count = stringRedisTemplate.opsForGeo().geoAdd(GEO_KEY, new Point(spot.getLongitude(),spot.getLatitude()), spot.getId());
//            if (count == null || count == 0) {
//                System.out.println("Spot already exists in Redis or failed to add: " + spot.getId());
//            }
//        });
//    }

    @Override
    public Page<Spot> page(SpotPageParam spotPageParam) {
        QueryWrapper<Spot> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(spotPageParam.getSpotName())) {
            queryWrapper.lambda().like(Spot::getSpotName, spotPageParam.getSpotName());
        }
        if(ObjectUtil.isNotEmpty(spotPageParam.getLocation())) {
            queryWrapper.lambda().eq(Spot::getAddress, spotPageParam.getLocation());
        }
        if(ObjectUtil.isAllNotEmpty(spotPageParam.getSortField(), spotPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(spotPageParam.getSortOrder());
            queryWrapper.orderBy(true, spotPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(spotPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(Spot::getSort);
        }
        Page<Spot> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SpotAddParam spotAddParam) {
        Spot spot = BeanUtil.toBean(spotAddParam, Spot.class);
//        stringRedisTemplate.opsForGeo().add(GEO_KEY, new Point(spot.getLongitude(),spot.getLatitude()), spot.getId());
        this.save(spot);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SpotEditParam spotEditParam) {
        Spot spot = this.queryEntity(spotEditParam.getId());
        BeanUtil.copyProperties(spotEditParam, spot);
//        stringRedisTemplate.opsForGeo().add(GEO_KEY, new Point(spot.getLongitude(),spot.getLatitude()), spot.getId());
        this.updateById(spot);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<SpotIdParam> spotIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(spotIdParamList, SpotIdParam::getId));
    }

    @Override
    public Spot detail(SpotIdParam spotIdParam) {
        return this.queryEntity(spotIdParam.getId());
    }

    @Override
    public Spot queryEntity(String id) {
        Spot spot = this.getById(id);
        if(ObjectUtil.isEmpty(spot)) {
            throw new CommonException("景点表不存在，id值为：{}", id);
        }
        return spot;
    }
//    /*获取首页热门景点*/
//    @Override
//    public List<Spot> getRedSpot() {
//        // 调用带参数的方法，传入默认分类1（景点）
//        return this.getRedSpot(1);
//    }

    /*根据分类获取首页热门景点*/
    @Override
    public List<Spot> getRedSpot(Integer category, String userId, String invitationUserId) {
        // 新增判断是否是几个特定上级邀请的用户, 19号注册的四个一级分销
        boolean flag = false;
        List<String> pingbiUserids = Lists.newArrayList();
        pingbiUserids.add("1946370683962671105");
        pingbiUserids.add("1946373774623653889");
        pingbiUserids.add("1946376836868227073");
        pingbiUserids.add("1946386581641510914");
        // 查找特定一级邀请的二级
        List<BizFzUser> bizFzUserList = bizFzUserMapper.selectList(new LambdaQueryWrapper<BizFzUser>().in(BizFzUser::getParentId, pingbiUserids));
        for (BizFzUser bizFzUser : bizFzUserList) {
            pingbiUserids.add(bizFzUser.getId());
        }

        if (pingbiUserids.contains(invitationUserId) || pingbiUserids.contains(userId)) {
            flag = true;
        }

        LambdaQueryWrapper<Spot> spotLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 添加分类过滤条件
        spotLambdaQueryWrapper.eq(Spot::getCategory, category);
        spotLambdaQueryWrapper.eq(Spot::getDeleteFlag, "NOT_DELETE");
        if (flag) {
            // 特定人群过滤掉：出海海钓（可当天预定）、潜水、潜水+海钓的景点
            spotLambdaQueryWrapper.ne(Spot::getId, "1916487120975052801");
            spotLambdaQueryWrapper.ne(Spot::getId, "1916487120975052802");
            spotLambdaQueryWrapper.ne(Spot::getId, "1929050968810659846");
            spotLambdaQueryWrapper.ne(Spot::getId, "1929050968810659847");
            spotLambdaQueryWrapper.ne(Spot::getId, "1929050968810659848");
        }
        spotLambdaQueryWrapper.orderByDesc(Spot::getRate);
        List<Spot> spotList = this.list(spotLambdaQueryWrapper);
        for (Spot spot : spotList) {
            LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Ticket::getSpotId,spot.getId());
            queryWrapper.orderByAsc(Ticket::getPrice);
            queryWrapper.last("limit 1");
            Ticket ticket = ticketService.getOne(queryWrapper);
            if (null != ticket) {
                spot.setMinPrice(ticket.getPrice());
            }
        }
        return spotList;
    }

    @Override
    public List<Namelist> namelist() {
        LambdaQueryWrapper<Spot> spotLambdaQueryWrapper = new LambdaQueryWrapper<>();
        spotLambdaQueryWrapper.select(Spot::getSpotName,Spot::getId,Spot::getCover,Spot::getRate,Spot::getStartLevel);
        List<Spot> list = this.list(spotLambdaQueryWrapper);
        return BeanUtil.copyToList(list, Namelist.class);
    }



    @Override
    public void updateSpotScoreInDatabase(String spotId, double newSpotScore) {
        Spot spot = this.getById(spotId);
        spot.setRate(BigDecimal.valueOf(newSpotScore));
        this.updateById(spot);
    }

    @Override
    public Spot getOrderByspotName(String orderId) {
        return spotMapper.getOrderByspotName(orderId);
    }

    @Override
    public List<Spot> spotBook(String spotname, String userId, String invitationUserId) {
        // 新增判断是否是几个特定上级邀请的用户, 19号注册的四个一级分销
        boolean flag = false;
        List<String> pingbiUserids = Lists.newArrayList();
        pingbiUserids.add("1946370683962671105");
        pingbiUserids.add("1946373774623653889");
        pingbiUserids.add("1946376836868227073");
        pingbiUserids.add("1946386581641510914");
        // 查找特定一级邀请的二级
        List<BizFzUser> bizFzUserList = bizFzUserMapper.selectList(new LambdaQueryWrapper<BizFzUser>().in(BizFzUser::getParentId, pingbiUserids));
        for (BizFzUser bizFzUser : bizFzUserList) {
            pingbiUserids.add(bizFzUser.getId());
        }

        if (pingbiUserids.contains(invitationUserId) || pingbiUserids.contains(userId)) {
            flag = true;
        }
        List<Spot> spots = spotMapper.spotBook(spotname, flag);
        return spots;
    }

}
